module FIFO2( 
            clk, 
            rstp, 
            din, 
            readp, 
            writep, 
            dout, 
            emptyp, 
            fullp); 
             
input   clk;
input   rstp;
input   [15:0] din;
input   readp;
input   writep; 
 
output  [15:0] dout;
output  emptyp;
output  fullp;
 
parameter  DEPTH=10'd1024,MAX_COUNT=10'd1024;
            
reg [15:0] dout; 
reg        emptyp;
reg        fullp; 
 
reg [2:0] tail;
reg [2:0] head;
reg [2:0] count; 
reg [15:0] fifomem[0:7]; 
 
reg sr_read_write_empty; 
 
 
always @(posedge clk) 
 	begin 
    if(rstp==1)
		sr_read_write_empty <= 1'b0; 
   	else if(readp==1'b1 && emptyp==1'b1 && writep==1'b1) 
     		sr_read_write_empty <= 1'b1; 
    else 
		sr_read_write_empty <= 1'b0; 
 	end 

always @(posedge clk) 
  	begin 
    if(rstp==1) 
      	dout <= 16'h0000; 
    else if(readp==1'b1 && emptyp==1'b0) 
      	dout <= fifomem[tail];
  	end 
   
always @(posedge clk) 
  	begin 
    if(rstp==1'b0 && writep==1'b1 && fullp==1'b0) 
       	fifomem[head] <= din; 
  	end 

always @(posedge clk) 
 	begin 
   	if(rstp==1'b1) 
     	head <= 2'b00; 
   	else 
     	begin 
       	if(writep==1'b1 && fullp==1'b0) 
         	head <= head +1'b1; 
     	end 
 	end 

always @(posedge clk) 
 	begin 
   	if(rstp==1'b1) 
     	tail <= 2'b00; 
   	else 
     	begin 
       	if(readp==1'b1 && emptyp==1'b0) 
         	tail <= tail +1'b1; 
     	end 
 	end       

always @(posedge clk) 
  	begin 
    if(rstp==1'b1) 
      	count <=2'b00; 
    else 
      	begin 
        case({readp,writep}) 
          2'b00: 
             count <=count; 
          2'b01: 
             if(count!=MAX_COUNT) 
               count <= count + 1; 
          2'b10: 
             if(count!=2'b00) 
               count <= count - 1; 
          2'b11: 
          if(sr_read_write_empty==1'b1) 
             	count <= count + 1; 
          else 
               	count <= count; 
          default: 
               	count <= count; 
        endcase 
       end 
    end 

always @(count) 
  	begin 
    if(count==2'b00) 
      	emptyp <= 1'b1; 
    else 
      	emptyp <= 1'b0;  
  	end 

always @(count) 
  	begin 
    if(count==MAX_COUNT) 
      	fullp <= 1'b1; 
    else
      	fullp <= 1'b0;  
  	end
endmodule